<?php

namespace frontend\controllers;

use Yii;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\Sensor;
use common\models\Command;
use common\models\Config;
use yii\helpers\ArrayHelper;
use common\models\IocScanning;

/**
 * Investigate controller
 */
class InvestigateController extends Controller {

    /**
     * @inheritdoc
     */
    public function behaviors() {
        if (Config::getLicense()['sensorNowCount'] == 0) {
            $rules = [];
        } else {
            $rules = [
                [
                    'actions' => [''],
                    'allow' => true,
                    'roles' => ['?']
                ],
                [
                    'actions' => ['index', 'send-command', 'get-result', 'get-sensor', 'computer', 'file', 'file-transfer', 'signer', 'domain', 'user', 'download-ioc-template', 'get-ioc-list', 'test-download-csv', 'download-csv',],
                    'allow' => true,
                    'roles' => ['@']
                ],
                [
                    'actions' => [],
                    'allow' => true,
                    'roles' => ['admin']
                ]
            ];
        }
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['index', 'send-command', 'get-result', 'get-sensor', 'computer', 'file', 'file-transfer', 'signer', 'domain', 'user', 'download-ioc-template', 'upload-file', 'get-ioc-list', 'test-download-csv', 'download-csv', 'del-csv'],
                'rules' => $rules
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                // 'logout' => ['post'],
                // 'test' => ['post'],
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function actions() {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
        ];
    }

    /**
     * Displays homepage.
     *
     * @return mixed
     */
    public $enableCsrfValidation = false;

    private function isAPI() {
        $headers = Yii::$app->request->headers;
        if (stristr($headers['accept'], 'application/json') !== false) {
            Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        } else {
            Yii::$app->response->format = \yii\web\Response::FORMAT_XML;
        }
    }

    public function actionIndex() {
        return $this->render('index');
    }

    //计算机安全调查
    public function actionComputer() {
        $this->isAPI();
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        $current_page = $parames['current_page'] ? $parames['current_page'] : 1;
        $per_page_count = $parames['per_page_count'] ? $parames['per_page_count'] : 15;
        $from = $current_page == 1 ? 0 : ($current_page - 1) * $per_page_count;
        $filter = [
            'from' => $from,
            'size' => $per_page_count,
            'query' => [
                'bool' => [
                    'must' => [
                        0 => ['match' => ['SensorID' => $parames['SensorID']]],
                        1 => ['match' => ['EventAction' => $parames['EventAction']]],
                        2 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        $data = self::esRequest(json_encode($filter));
        //判断调查计算机的什么东西
        $final_data = [];
        if ($parames['EventAction'] == 'USER_LOGON') {
            foreach ($data['hits']['hits'] as $key => $value) {
                $final_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
                $final_data[$key]['ComputerName'] = $value['_source']['ComputerName'];
                $final_data[$key]['UserName'] = $value['_source']['TarObj']['UserName'];
                if ($value['_source']['TarObj']['LogonType'] == 'RDP') {
                    $final_data[$key]['LogonType'] = '远程';
                } else if ($value['_source']['TarObj']['LogonType'] == 'LOCAL') {
                    $final_data[$key]['LogonType'] = '本地';
                } else {
                    $final_data[$key]['LogonType'] = '';
                }
            }
        } else if ($parames['EventAction'] == 'NETWORK_CONNECT') {
            foreach ($data['hits']['hits'] as $key => $value) {
                $final_data[$key]['UserName'] = $value['_source']['SrcObj']['UserName'];
                $final_data[$key]['ComputerName'] = $value['_source']['ComputerName'];
                $final_data[$key]['ProcessName'] = $value['_source']['SrcObj']['ProcessName'];
                $final_data[$key]['PID'] = $value['_source']['SrcObj']['PID'];
                $final_data[$key]['CommandLine'] = $value['_source']['SrcObj']['CommandLine'];
                $final_data[$key]['LocalPort'] = $value['_source']['TarObj']['LocalPort'];
                $final_data[$key]['RemoteIP'] = $value['_source']['TarObj']['RemoteIP'];
                $final_data[$key]['RemotePort'] = $value['_source']['TarObj']['RemotePort'];
                $final_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
            }
        } else if ($parames['EventAction'] == 'USB_PLUG_ARRIVAL') {
            foreach ($data['hits']['hits'] as $key => $value) {
                $final_data[$key]['ComputerName'] = key_exists('ComputerName', $value['_source']) ? $value['_source']['ComputerName'] : '';
                $final_data[$key]['VolName'] = key_exists('VolName', $value['_source']['TarObj']) ? $value['_source']['TarObj']['VolName'] : '';
                $final_data[$key]['DriverLetter'] = key_exists('DriverLetter', $value['_source']['TarObj']) ? $value['_source']['TarObj']['DriverLetter'] : '';
                $final_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
            }
        } else if ($parames['EventAction'] == 'ADD_SCHD_TASK') {
            foreach ($data['hits']['hits'] as $key => $value) {
                $final_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
                $final_data[$key]['CommandLine'] = $value['_source']['SrcObj']['CommandLine'];
            }
        } else {
            return ['status' => 'fail', 'errorMessage' => 'Bad Request'];
        }
        $return = ['status' => 'success', 'data' => $final_data, 'total_count' => $data['hits']['total'], 'current_page' => $current_page, 'max_page' => ceil($data['hits']['total'] / $per_page_count)];
        return $return;
    }

    //文件安全调查
    public function actionFile() {
        $this->isAPI();
        //生成from和size
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        $current_page = $parames['current_page'] ? $parames['current_page'] : 1;
        $per_page_count = $parames['per_page_count'] ? $parames['per_page_count'] : 15;
        $from = $current_page == 1 ? 0 : ($current_page - 1) * $per_page_count;
        //查询语句
        $filter = [
            'from' => $from,
            'size' => $per_page_count,
            'query' => [
                'bool' => [
                    'should' => [
                        0 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PROCESS']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ],
                                'must_not' => []
                            ]
                        ],
                        1 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PROCESS']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ],
                                'must_not' => []
                            ]
                        ],
                        2 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_FILE']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ],
                                'must_not' => []
                            ]
                        ],
                        3 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PE_FILE']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ],
                                'must_not' => []
                            ]
                        ],
                        4 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'IMAGE_LOAD_TO_SENSITIVE']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ],
                                'must_not' => []
                            ]
                        ]
                    ]
                ]
            ],
            'aggs' => [
                'author_count' => [
                    'cardinality' => [
                        'field' => 'SensorID'
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        //过滤参数
        if ($parames['FileName'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['SrcObj.ProcessName' => $parames['FileName']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['TarObj.ProcessName' => $parames['FileName']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match_phrase' => ['TarObj.FilePath' => $parames['FileName']]]);
            array_push($filter['query']['bool']['should'][3]['bool']['must'], ['match_phrase' => ['TarObj.FilePath' => $parames['FileName']]]);
            array_push($filter['query']['bool']['should'][4]['bool']['must'], ['match_phrase' => ['TarObj.FilePath' => $parames['FileName']]]);
        }
        if ($parames['MD5OrSHA256'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['SrcObj.MD5' => $parames['MD5OrSHA256']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['TarObj.MD5' => $parames['MD5OrSHA256']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match' => ['TarObj.MD5' => $parames['MD5OrSHA256']]]);
            array_push($filter['query']['bool']['should'][3]['bool']['must'], ['match' => ['TarObj.MD5' => $parames['MD5OrSHA256']]]);
            array_push($filter['query']['bool']['should'][4]['bool']['must'], ['match' => ['TarObj.MD5' => $parames['MD5OrSHA256']]]);
        }
        if ($parames['CommandLine'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['SrcObj.CommandLine' => $parames['CommandLine']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['TarObj.CommandLine' => $parames['CommandLine']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match' => ['TarObj.CommandLine' => $parames['CommandLine']]]);
            array_push($filter['query']['bool']['should'][3]['bool']['must'], ['match' => ['TarObj.CommandLine' => $parames['CommandLine']]]);
            array_push($filter['query']['bool']['should'][4]['bool']['must'], ['match' => ['TarObj.CommandLine' => $parames['CommandLine']]]);
        }
        if ($parames['ComputerName'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['SrcObj.ComputerName' => $parames['ComputerName']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['TarObj.ComputerName' => $parames['ComputerName']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match' => ['TarObj.ComputerName' => $parames['ComputerName']]]);
            array_push($filter['query']['bool']['should'][3]['bool']['must'], ['match' => ['TarObj.ComputerName' => $parames['ComputerName']]]);
            array_push($filter['query']['bool']['should'][4]['bool']['must'], ['match' => ['TarObj.ComputerName' => $parames['ComputerName']]]);
        }
        if ($parames['IgnorePath'] != '') {
            if (substr($parames['IgnorePath'], -1) != '\\') {
                $parames['IgnorePath'] .= '\\';
            }
            $parames['IgnorePath'] = strtolower(addcslashes($parames['IgnorePath'], '+-=&&||><!(){}[]^"~*?:\/'));
//            p($parames['IgnorePath']);
//            die;
//            array_push($filter['query']['bool']['should'][0]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath']]]]);c:\windows\explorer.exe
//            array_push($filter['query']['bool']['should'][1]['bool']['must_not'], ['wildcard' => ['TarObj.ImagePath.keyword' => ['value' => $parames['IgnorePath']]]]);
//            array_push($filter['query']['bool']['should'][2]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath']]]]); . "[^\\]$"
//            array_push($filter['query']['bool']['should'][3]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath']]]]);c:\\\windows\\\((?!\\\).)*$这个
            array_push($filter['query']['bool']['should'][0]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath'] . '*']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must_not'], ['wildcard' => ['TarObj.ImagePath.keyword' => ['value' => $parames['IgnorePath'] . '*']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath'] . '*']]]);
//            array_push($filter['query']['bool']['should'][3]['bool']['must_not'], ['query_string' => ['default_field' => 'SrcObj.ImagePath.keyword', 'query' => $parames['IgnorePath'] . '[^b]*$']]);
            array_push($filter['query']['bool']['should'][3]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath'] . '*']]]);
            array_push($filter['query']['bool']['should'][4]['bool']['must_not'], ['wildcard' => ['SrcObj.ImagePath.keyword' => ['value' => $parames['IgnorePath'] . '*']]]);
//            array_push($ignore_condition, ['match' => ['SrcObj.ImagePath' => $parames['IgnorePath']]]);
//            array_push($ignore_condition, ['match' => ['TarObj.ImagePath' => $parames['IgnorePath']]]);
        }
        if ($parames['IgnoreParentName'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must_not'], ['term' => ['SrcObj.ParentName.keyword' => $parames['IgnoreParentName']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must_not'], ['term' => ['TarObj.ParentName.keyword' => $parames['IgnoreParentName']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must_not'], ['term' => ['SrcObj.ParentName.keyword' => $parames['IgnoreParentName']]]);
            array_push($filter['query']['bool']['should'][3]['bool']['must_not'], ['term' => ['SrcObj.ParentName.keyword' => $parames['IgnoreParentName']]]);
            array_push($filter['query']['bool']['should'][4]['bool']['must_not'], ['term' => ['SrcObj.ParentName.keyword' => $parames['IgnoreParentName']]]);
//            array_push($filter['query']['bool']['should'][0]['bool']['must_not'], ['query_string' => ['default_field' => 'SrcObj.ParentName.keyword', 'query' => $parames['IgnoreParentName']]]);
//            array_push($filter['query']['bool']['should'][1]['bool']['must_not'], ['query_string' => ['default_field' => 'TarObj.ParentName.keyword', 'query' => $parames['IgnoreParentName']]]);
//            array_push($filter['query']['bool']['should'][2]['bool']['must_not'], ['query_string' => ['default_field' => 'TarObj.ParentName.keyword', 'query' => $parames['IgnoreParentName']]]);
//            array_push($filter['query']['bool']['should'][3]['bool']['must_not'], ['query_string' => ['default_field' => 'TarObj.ParentName.keyword', 'query' => $parames['IgnoreParentName']]]);
//            array_push($ignore_condition, ['query_string' => ['default_field' => 'SrcObj.ParentName.keyword', 'query' => $parames['IgnoreParentName']]]);
//            array_push($ignore_condition, ['query_string' => ['default_field' => 'TarObj.ParentName.keyword', 'query' => $parames['IgnoreParentName']]]);
//            array_push($ignore_condition, ['match' => ['SrcObj.ParentName' => $parames['IgnoreParentName']]]);
//            array_push($ignore_condition, ['match' => ['TarObj.ParentName' => $parames['IgnoreParentName']]]);
        }
//        if ($ignore_condition) {
//            $filter['query']['bool']['must_not'] = $ignore_condition;
//        }
        //查询数据

        $data = self::esRequest(json_encode($filter));
//        print_r($data);
//        die;
        $file_data = [];
        $SensorID = [];
        foreach ($data['hits']['hits'] as $key => $value) {
            array_push($SensorID, $value['_source']['SensorID']);
            $file_data[$key]['SensorID'] = $value['_source']['SensorID'];
//            $file_data[$key]['UserName'] = $value['_source']['SrcObj']['UserName'];
//            $file_data[$key]['ProcessName'] = $value['_source']['SrcObj']['ProcessName'];
//            $file_data[$key]['PID'] = $value['_source']['SrcObj']['PID'];
//            $file_data[$key]['CommandLine'] = $value['_source']['SrcObj']['CommandLine'];
            $file_data[$key]['ComputerName'] = $value['_source']['ComputerName'];
            $file_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
            $file_data[$key]['EventAction'] = $value['_source']['EventAction'];
//            $file_data[$key]['FilePath'] = $value['_source']['TarObj']['FilePath']; //这个页面可能用不到
            if (in_array($value['_source']['EventAction'], ['CREATE_FILE', 'CREATE_PE_FILE', 'IMAGE_LOAD_TO_SENSITIVE'])) {
                $file_data[$key]['MD5'] = $value['_source']['TarObj']['MD5'];
                $file_data[$key]['UserName'] = $value['_source']['SrcObj']['UserName'];
                $file_data[$key]['ProcessName'] = $value['_source']['SrcObj']['ProcessName'];
                $file_data[$key]['PID'] = $value['_source']['SrcObj']['PID'];
                $file_data[$key]['CommandLine'] = $value['_source']['SrcObj']['CommandLine'];
                $file_data[$key]['FileName'] = substr($value['_source']['TarObj']['FilePath'], strripos($value['_source']['TarObj']['FilePath'], '\\') + 1);
                $file_data[$key]['ParentName'] = $value['_source']['SrcObj']['ParentName'];
                $file_data[$key]['ChildProcessNameList'] = '';
            } else if ($value['_source']['EventAction'] == 'CREATE_PROCESS') {
                //判断是从src还是从tar中查询出来的
                if (($parames['FileName'] == $value['_source']['SrcObj']['ProcessName'] && $parames['FileName']) || ($parames['MD5OrSHA256'] == $value['_source']['SrcObj']['MD5'] && $parames['MD5OrSHA256'])) {
                    $file_data[$key]['MD5'] = $value['_source']['SrcObj']['MD5'];
                    $file_data[$key]['UserName'] = $value['_source']['SrcObj']['UserName'];
                    $file_data[$key]['ProcessName'] = $value['_source']['SrcObj']['ProcessName'];
                    $file_data[$key]['PID'] = $value['_source']['SrcObj']['PID'];
                    $file_data[$key]['CommandLine'] = $value['_source']['SrcObj']['CommandLine'];
                    $file_data[$key]['FileName'] = $value['_source']['SrcObj']['ProcessName'];
                    $file_data[$key]['ParentName'] = $value['_source']['SrcObj']['ParentName'];
                    $file_data[$key]['ChildProcessNameList'] = $value['_source']['TarObj']['ProcessName'];
                } else {
                    $file_data[$key]['MD5'] = $value['_source']['TarObj']['MD5'];
                    $file_data[$key]['UserName'] = $value['_source']['TarObj']['UserName'];
                    $file_data[$key]['ProcessName'] = $value['_source']['TarObj']['ProcessName'];
                    $file_data[$key]['PID'] = $value['_source']['TarObj']['PID'];
                    $file_data[$key]['CommandLine'] = $value['_source']['TarObj']['CommandLine'];
                    $file_data[$key]['FileName'] = $value['_source']['TarObj']['ProcessName'];
                    $file_data[$key]['ParentName'] = $value['_source']['TarObj']['ParentName'];
                    $file_data[$key]['ChildProcessNameList'] = '';
                }
            }
        }
        //添加sensor的IP
        $sensor = Sensor::getSensorIP($SensorID);
        foreach ($file_data as $key => $value) {
            $file_data[$key]['IP'] = $sensor[$value['SensorID']]['IP'];
        }
        $final_data['FileComputer'] = $file_data;
        $filter['from'] = 0;
        $filter['size'] = 1;
        $filter['sort'] = ['Timestamp' => ['order' => 'asc']];
        $desc_file_data = self::esRequest(json_encode($filter));
        $final_data['MD5'] = '';
        $final_data['FileName'] = '';
        if (array_key_exists(0, $desc_file_data['hits']['hits'])) {
            $first_event = $desc_file_data['hits']['hits'][0]['_source'];
            if (in_array($first_event['EventAction'], ['CREATE_FILE', 'CREATE_PE_FILE', 'IMAGE_LOAD_TO_SENSITIVE'])) {
                $final_data['MD5'] = $first_event['TarObj']['MD5'];
                $final_data['FileName'] = substr($first_event['TarObj']['FilePath'], strripos($first_event['TarObj']['FilePath'], '\\') + 1);
            } else {
                if (($parames['FileName'] == $first_event['SrcObj']['ProcessName'] && $parames['FileName']) || ($parames['MD5OrSHA256'] == $first_event['SrcObj']['MD5'] && $parames['MD5OrSHA256'])) {
                    $final_data['MD5'] = $first_event['SrcObj']['MD5'];
                    $final_data['FileName'] = $first_event['SrcObj']['ProcessName'];
                } else {
                    $final_data['MD5'] = $first_event['TarObj']['MD5'];
                    $final_data['FileName'] = $first_event['TarObj']['ProcessName'];
                }
            }
        }
        $final_data['LastComputerName'] = $file_data ? $file_data[0]['ComputerName'] : '';
        $final_data['FristComputerName'] = array_key_exists(0, $desc_file_data['hits']['hits']) ? $desc_file_data['hits']['hits'][0]['_source']['ComputerName'] : '';
        $final_data['LastTime'] = $file_data ? $file_data[0]['Time'] : '';
        $final_data['FristTime'] = array_key_exists(0, $desc_file_data['hits']['hits']) ? date('Y-m-d H:i:s', $desc_file_data['hits']['hits'][0]['_source']['Timestamp'] / 1000) : '';
        $return = ['status' => 'success', 'data' => $final_data, 'total_count' => $data['hits']['total'], 'computer_count' => array_key_exists('aggregations', $data) ? $data['aggregations']['author_count']['value'] : 0, 'current_page' => $current_page, 'max_page' => ceil($data['hits']['total'] / $per_page_count)];
        return $return;
    }

    //文件传输安全调查
    public function actionFileTransfer() {
        $this->isAPI();
        //生成from和size
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        $current_page = $parames['current_page'] ? $parames['current_page'] : 1;
        $per_page_count = $parames['per_page_count'] ? $parames['per_page_count'] : 15;
        $from = $current_page == 1 ? 0 : ($current_page - 1) * $per_page_count;
        //查询语句
        $filter = [
            'from' => $from,
            'size' => $per_page_count,
            'query' => [
                'bool' => [
                    'must' => [
                        0 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                    ],
                    'filter' => [
                        'bool' => [
                            'should' => [
                                0 => ['match' => ['EventAction' => 'CREATE_FILE']],
                                1 => ['match' => ['EventAction' => 'CREATE_PE_FILE']]
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        //过滤参数
        if ($parames['ProcessName'] != '') {
            array_push($filter['query']['bool']['must'], ['match_phrase' => ['SrcObj.ProcessName' => $parames['ProcessName']]]);
        }
        if ($parames['ComputerName'] != '') {
            array_push($filter['query']['bool']['must'], ['match_phrase' => ['ComputerName' => $parames['ComputerName']]]);
        }
        //查询数据
        $data = self::esRequest(json_encode($filter));
        $filetransfer_data = [];
        $SensorID = [];
        foreach ($data['hits']['hits'] as $key => $value) {
            array_push($SensorID, $value['_source']['SensorID']);
            $filetransfer_data[$key]['SensorID'] = $value['_source']['SensorID'];
            $filetransfer_data[$key]['ComputerName'] = $value['_source']['ComputerName'];
            $filetransfer_data[$key]['FileName'] = $value['_source']['TarObj']['FilePath'];
            $filetransfer_data[$key]['ProcessName'] = $value['_source']['SrcObj']['ProcessName'];
            $filetransfer_data[$key]['PID'] = $value['_source']['SrcObj']['PID'];
            $filetransfer_data[$key]['FileHashList']['MD5'] = $value['_source']['TarObj']['MD5'];
            $filetransfer_data[$key]['EventAction'] = $value['_source']['EventAction'];
            $filetransfer_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
        }
        //添加sensor的IP
        $sensor = Sensor::getSensorIP($SensorID);
        foreach ($filetransfer_data as $key => $value) {
            $filetransfer_data[$key]['IP'] = $sensor[$value['SensorID']]['IP'];
        }
        $return = ['status' => 'success', 'data' => $filetransfer_data, 'total_count' => $data['hits']['total'], 'current_page' => $current_page, 'max_page' => ceil($data['hits']['total'] / $per_page_count)];
        return $return;
    }

    //签名安全调查
    public function actionSigner() {
        $this->isAPI();
        //生成from和size
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        $current_page = $parames['current_page'] ? $parames['current_page'] : 1;
        $per_page_count = $parames['per_page_count'] ? $parames['per_page_count'] : 15;
        $from = $current_page == 1 ? 0 : ($current_page - 1) * $per_page_count;
        $filter = [
            'from' => $from,
            'size' => $per_page_count,
            'query' => [
                'bool' => [
                    'should' => [
                        0 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PE_FILE']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]],
                                    2 => ['query_string' => ['default_field' => 'TarObj.Signer.keyword', 'query' => $parames['Signer']]]
//                                    2 => ['match' => ['TarObj.Signer' => $parames['Signer']]],
//                                    2 => ['match' => ['TarObj.Signer.keyword' => $parames['Signer']]],
                                ]
                            ]
                        ],
                        1 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PROCESS']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]],
                                    2 => ['query_string' => ['default_field' => 'SrcObj.Signer.keyword', 'query' => $parames['Signer']]]
//                                    2 => ['match' => ['SrcObj.Signer' => $parames['Signer']]],
                                ]
                            ]
                        ],
                        2 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PROCESS']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]],
                                    2 => ['query_string' => ['default_field' => 'TarObj.Signer.keyword', 'query' => $parames['Signer']]]
//                                    2 => ['match' => ['TarObj.Signer' => $parames['Signer']]]
                                ]
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        //查询
        $data = self::esRequest(json_encode($filter));
        $signer_data = [];
        foreach ($data['hits']['hits'] as $key => $value) {
            $signer_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
            $signer_data[$key]['EventAction'] = $value['_source']['EventAction'];
            if ($value['_source']['EventAction'] == 'CREATE_PE_FILE') {
                $signer_data[$key]['FileName'] = substr($value['_source']['TarObj']['FilePath'], strripos($value['_source']['TarObj']['FilePath'], '\\') + 1);
                $signer_data[$key]['Signer'] = $value['_source']['TarObj']['Signer'];
                $signer_data[$key]['MD5'] = key_exists('MD5', $value['_source']['TarObj']) ? $value['_source']['TarObj']['MD5'] : '';
            } else if ($value['_source']['EventAction'] == 'CREATE_PROCESS' && is_int(stripos($value['_source']['TarObj']['Signer'], $parames['Signer']))) {
//                $signer_data[$key]['FileName'] = key_exists('FileName', $value['_source']['TarObj']) ? $value['_source']['TarObj']['FileName'] : '';
                $signer_data[$key]['FileName'] = $value['_source']['TarObj']['ProcessName'];
                $signer_data[$key]['Signer'] = $value['_source']['TarObj']['Signer'];
                $signer_data[$key]['MD5'] = key_exists('MD5', $value['_source']['TarObj']) ? $value['_source']['TarObj']['MD5'] : '';
            } else if ($value['_source']['EventAction'] == 'CREATE_PROCESS' && is_int(stripos($value['_source']['SrcObj']['Signer'], $parames['Signer']))) {
//                $signer_data[$key]['FileName'] = key_exists('FileName', $value['_source']['SrcObj']) ? $value['_source']['SrcObj']['FileName'] : '';
                $signer_data[$key]['FileName'] = $value['_source']['SrcObj']['ProcessName'];
                $signer_data[$key]['Signer'] = $value['_source']['SrcObj']['Signer'];
                $signer_data[$key]['MD5'] = key_exists('MD5', $value['_source']['SrcObj']) ? $value['_source']['SrcObj']['MD5'] : '';
            }
        }
        $return = ['status' => 'success', 'data' => $signer_data, 'total_count' => $data['hits']['total'], 'current_page' => $current_page, 'max_page' => ceil($data['hits']['total'] / $per_page_count)];
        return $return;
    }

    //域名安全调查
    public function actionDomain() {
        $this->isAPI();
        //生成from和size
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        $current_page = $parames['current_page'] ? $parames['current_page'] : 1;
        $per_page_count = $parames['per_page_count'] ? $parames['per_page_count'] : 15;
        $from = $current_page == 1 ? 0 : ($current_page - 1) * $per_page_count;
        //查询语句
        $filter = [
            'from' => $from,
            'size' => $per_page_count,
            'query' => [
                'bool' => [
                    'should' => [
                        0 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'NETWORK_CONNECT']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ]
                            ]
                        ],
                        1 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'DNS_QUERY']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ]
                            ]
                        ],
                        2 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'HTTP_REQUEST']],
                                    1 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                                ]
                            ]
                        ]
                    ]
//                    'must' => [
//                        0 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
//                    ],
//                    'filter' => [
//                        'bool' => [
//                            'should' => [
//                                0 => ['match' => ['EventAction' => 'NETWORK_CONNECT']],
//                                1 => ['match' => ['EventAction' => 'DNS_QUERY']],
//                                2 => ['match' => ['EventAction' => 'HTTP_REQUEST']]
//                            ]
//                        ]
//                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        //过滤参数
        if ($parames['URL'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['query_string' => ['default_field' => 'TarObj.DomainName.keyword', 'query' => $parames['URL']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['query_string' => ['default_field' => 'TarObj.DomainName.keyword', 'query' => $parames['URL']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['query_string' => ['default_field' => 'TarObj.DomainName.keyword', 'query' => $parames['URL']]]);
//            array_push($filter['query']['bool']['must'], ['match' => ['TarObj.DomainName' => $parames['URL']]]);
        }
        if ($parames['IP'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['TarObj.RemoteIP' => $parames['IP']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['TarObj.RemoteAdd' => $parames['IP']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match' => ['TarObj.RemoteAdd' => $parames['IP']]]);
//            array_push($filter['query']['bool']['must'], ['match' => ['TarObj.RemoteIP' => $parames['IP']]]);
        }
        if ($parames['Port'] != '') {
            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['TarObj.RemotePort' => $parames['Port']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['TarObj.RemotePort' => $parames['Port']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match' => ['TarObj.RemotePort' => $parames['Port']]]);
//            array_push($filter['query']['bool']['must'], ['match' => ['TarObj.RemotePort' => $parames['Port']]]);
        }
        if ($parames['IgnoreProcessName'] != '') {
            $filter['query']['bool']['should'][0]['bool']['must_not'] = [];
            $filter['query']['bool']['should'][1]['bool']['must_not'] = [];
            $filter['query']['bool']['should'][2]['bool']['must_not'] = [];
            array_push($filter['query']['bool']['should'][0]['bool']['must_not'], ['query_string' => ['default_field' => 'SrcObj.ProcessName.keyword', 'query' => $parames['IgnoreProcessName']]]);
            array_push($filter['query']['bool']['should'][1]['bool']['must_not'], ['query_string' => ['default_field' => 'SrcObj.ProcessName.keyword', 'query' => $parames['IgnoreProcessName']]]);
            array_push($filter['query']['bool']['should'][2]['bool']['must_not'], ['query_string' => ['default_field' => 'SrcObj.ProcessName.keyword', 'query' => $parames['IgnoreProcessName']]]);
//            array_push($filter['query']['bool']['should'][0]['bool']['must'], ['match' => ['SrcObj.ProcessName' => $parames['IgnoreProcessName']]]);
//            array_push($filter['query']['bool']['should'][1]['bool']['must'], ['match' => ['SrcObj.ProcessName' => $parames['IgnoreProcessName']]]);
//            array_push($filter['query']['bool']['should'][2]['bool']['must'], ['match' => ['SrcObj.ProcessName' => $parames['IgnoreProcessName']]]);
//            $filter['query']['bool']['must_not'] = ['match_phrase' => ['SrcObj.ProcessName' => $parames['IgnoreProcessName']]];
        }
        //查询数据
        $data = self::esRequest(json_encode($filter));
        $domain_data = [];
        $SensorID = [];
        foreach ($data['hits']['hits'] as $key => $value) {
            array_push($SensorID, $value['_source']['SensorID']);
            $domain_data[$key]['SensorID'] = $value['_source']['SensorID'];
            $domain_data[$key]['ComputerName'] = $value['_source']['ComputerName'];
            $domain_data[$key]['ProcessName'] = $value['_source']['SrcObj']['ProcessName'];
            $domain_data[$key]['PID'] = $value['_source']['SrcObj']['PID'];
            $domain_data[$key]['ImagePath'] = $value['_source']['SrcObj']['ImagePath'];
            $domain_data[$key]['EventAction'] = $value['_source']['EventAction'];
            $domain_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
            if ($value['_source']['EventAction'] == 'NETWORK_CONNECT') {
                $domain_data[$key]['search'] = $value['_source']['TarObj']['RemoteIP'] . ':' . $value['_source']['TarObj']['RemotePort'];
            } else if ($value['_source']['EventAction'] == 'DNS_QUERY') {
                $domain_data[$key]['search'] = $value['_source']['TarObj']['DomainName'];
            } else if ($value['_source']['EventAction'] == 'HTTP_REQUEST') {
                $domain_data[$key]['search'] = $value['_source']['TarObj']['RemoteAdd'] . ':' . $value['_source']['TarObj']['RemotePort'];
            }
        }
        //添加sensor的IP和status和ostype
        $sensor = Sensor::getSensorIP($SensorID);
        foreach ($domain_data as $key => $value) {
            $domain_data[$key]['IP'] = $sensor[$value['SensorID']]['IP'];
            $domain_data[$key]['status'] = $sensor[$value['SensorID']]['status'];
            $domain_data[$key]['OSType'] = $sensor[$value['SensorID']]['OSTypeShort'];
        }
        $return = ['status' => 'success', 'data' => $domain_data, 'total_count' => $data['hits']['total'], 'current_page' => $current_page, 'max_page' => ceil($data['hits']['total'] / $per_page_count)];
        return $return;
    }

    //用户安全调查
    public function actionUser() {
        $this->isAPI();
        //生成from和size
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        $current_page = $parames['current_page'] ? $parames['current_page'] : 1;
        $per_page_count = $parames['per_page_count'] ? $parames['per_page_count'] : 15;
        $from = $current_page == 1 ? 0 : ($current_page - 1) * $per_page_count;
        //查询语句
        $filter = [
            'from' => $from,
            'size' => $per_page_count,
            'query' => [
                'bool' => [
                    'must' => [
                        0 => ['range' => ['Timestamp' => ['gte' => $parames['start_time'] * 1000, 'lte' => $parames['end_time'] * 1000]]]
                    ],
                    'filter' => [
                        'bool' => [
                            'should' => [
                                0 => ['match' => ['EventAction' => 'USER_LOGON']],
                                1 => ['match' => ['EventAction' => 'CREATE_USER_ACCOUNT']]
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        //过滤参数
        //该参数以后加
//        if ($parames['Domain'] != '') {
//            array_push($filter['query']['bool']['must'], ['match_phrase' => ['TarObj.UserName' => $parames['Domain']]]);
//        }
        if ($parames['UserName'] != '') {
            array_push($filter['query']['bool']['must'], ['match_phrase' => ['TarObj.UserName' => $parames['UserName']]]);
        }
        //查询数据
        $data = self::esRequest(json_encode($filter));
        $user_data = [];
        $SensorID = [];
        foreach ($data['hits']['hits'] as $key => $value) {
            array_push($SensorID, $value['_source']['SensorID']);
            $user_data[$key]['SensorID'] = $value['_source']['SensorID'];
            $user_data[$key]['ComputerName'] = $value['_source']['ComputerName'];
            $user_data[$key]['Time'] = date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000);
            $user_data[$key]['Domain'] = '';
            $user_data[$key]['EventAction'] = $value['_source']['EventAction'];
            $user_data[$key]['UserName'] = $value['_source']['TarObj']['UserName'];
            if ($value['_source']['EventAction'] == 'USER_LOGON') {
                $user_data[$key]['LogonStatus'] = '成功';
            } else if ($value['_source']['EventAction'] == 'CREATE_USER_ACCOUNT') {
                $user_data[$key]['LogonStatus'] = '';
            }
        }
        //添加sensor的IP和status
        $sensor = Sensor::getSensorIP($SensorID);
        foreach ($user_data as $key => $value) {
            $user_data[$key]['IP'] = $sensor[$value['SensorID']]['IP'];
            $user_data[$key]['status'] = $sensor[$value['SensorID']]['status'];
        }
        $return = ['status' => 'success', 'data' => $user_data, 'total_count' => $data['hits']['total'], 'current_page' => $current_page, 'max_page' => ceil($data['hits']['total'] / $per_page_count)];
        return $return;
    }

    //下载ioc模板
    public function actionDownloadIocTemplate() {
        $this->isAPI();
        $frontend_url = Yii::getAlias('@frontend');
        //写入日志
        \YII::$app->response->sendFile($frontend_url . '/web/downloadfile/IOC.txt');
    }

    //上传文件
    public function actionUploadFile() {
        \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        //当上传错误时
        $return = ['status' => 'fail'];
        if (empty($_FILES['file']['name'])) {
            $return['errorMessage'] = '请选择.txt或.ioc的文件，重新上传';
            return $return;
        }
        if (strlen($_FILES['file']['name']) > 255) {
            $return['errorMessage'] = '文件名应小于255个字符';
            return $return;
        }
        //生成上传目录
//        $ioc_dir = Yii::getAlias('@frontend') . '/web/iocfile/';
        //写入日志
//        addLog('Download the template of IOCscan');
//        \YII::$app->response->sendFile($frontend_url . '/web/downloadfile/IOC.txt');
//        $upload_dir = '/opt/threatEye/ioc/';
        $tmp_file = $_FILES['file']['tmp_name'];
        if (filesize($tmp_file) / 1024 / 1024 > 10) {
            $return['errorMessage'] = '请选择小于10M的文件，重新上传';
            return $return;
        }
        $file_types = explode(".", $_FILES ['file'] ['name']);
        $file_type = $file_types[count($file_types) - 1];
        //生成唯一的文件名
        $time = microtime();
        $str = Yii::$app->user->identity->id . substr($time, -3) . substr($time, 2, 6) . mt_rand(10000, 99999);
        //判别是不是.txt和.ioc文件
        if (strtolower($file_type) != "txt" && strtolower($file_type) != "ioc") {
            $return['errorMessage'] = '请选择.txt或.ioc的文件，重新上传';
            return $return;
        }
        $contents['MD5'] = [];
        $contents['IP'] = [];
        $contents['URL'] = [];
        //判断用户传的是ioc还是txt
        if (strtolower($file_type) == 'ioc') {
            //获取文件内容
            $file_contents = file_get_contents($tmp_file);
            //解析内容
            $xml = simplexml_load_string($file_contents);
            $xmljson = json_encode($xml);
            $file_contents_arr = json_decode($xmljson, true)['definition']['Indicator']['IndicatorItem'];
            //解析文件内容
            foreach ($file_contents_arr as $value) {
                switch ($value['Context']['@attributes']['search']) {
                    case 'FileItem/Md5sum':
                        array_push($contents['MD5'], $value['Content']);
                        break;
                    case 'RouteEntryItem/Destination':
                        array_push($contents['IP'], $value['Content']);
                        break;
                    case 'UrlHistoryItem/URL':
                        array_push($contents['URL'], $value['Content']);
                        break;
                    case 'Network/DNS':
                        array_push($contents['URL'], $value['Content']);
                        break;
                    default:
                        break;
                }
            }
        } else if (strtolower($file_type) == 'txt') {
            $file = fopen($tmp_file, "r");
            $i = 0;
            $key = '';
            while (!feof($file)) {
                $content = fgets($file);
                if (trim($content) == '') {
                    continue;
                }
                if (in_array(trim($content), ['MD5', 'IP', 'URL'])) {
                    $key = trim($content);
                    continue;
                }
                if ($key == '') {
                    $return['errorMessage'] = 'txt文件格式错误';
                    return $return;
                }
                array_push($contents[$key], trim($content));
                $i++;
            }
            fclose($file);
        }

        //判断条件是否超过100个
        if (count($contents['MD5']) + count($contents['IP']) + count($contents['URL']) > 100) {
            $return['errorMessage'] = '文件中记录数不应大于100条';
            return $return;
        }
        //写入文件
        $ioc_file = Yii::getAlias('@frontend') . '/web/csvfile/' . $str . '.csv';
        $myfile = fopen($ioc_file, "w") or die("Unable to open file!");
        $md5_head = "用户,计算机名,IP地址,文件名,进程名,PID,哈希值,子进程,父进程,CommandLine,状态,时间\n";
        fwrite($myfile, iconv('UTF-8', 'GBK', $md5_head));
        $ioc_model = new IocScanning();
        $ioc_model->upload_file_name = $_FILES['file']['name'];
        $ioc_model->create_percent = 0;
        $ioc_model->create_status = 0;
        $ioc_model->create_time = time();
        $ioc_model->download_file_name = $str . '.csv';
        $ioc_model->save();
        $md5_contents = '';
        $ip_contents = '';
        $url_contents = '';
        //响应到前台
        echo json_encode(['status' => 'success'], true);
        session_write_close();
        fastcgi_finish_request();
        ignore_user_abort(true); // 后台运行
        set_time_limit(0);
        foreach ($contents['MD5'] as $v) {
            $m_data = $this->filterForMD5($v);
            //获取所有的sensor_id
            $SensorID = [];
            foreach ($m_data['hits']['hits'] as $key => $value) {
                array_push($SensorID, $value['_source']['SensorID']);
            }
            //添加sensor的IP和status
            $sensor = Sensor::getSensorIP($SensorID);
            foreach ($m_data['hits']['hits'] as $key => $value) {
                $md5_contents .= $value['_source']['SrcObj']['UserName'] . ',' . $value['_source']['ComputerName'] . ',' . (array_key_exists($value['_source']['SensorID'], $sensor) ? $sensor[$value['_source']['SensorID']]['IP'] : '' ) . ',';
                if ($value['_source']['EventAction'] == 'CREATE_PE_FILE') {
                    $md5_contents .= substr($value['_source']['TarObj']['FilePath'], strripos($value['_source']['TarObj']['FilePath'], '\\') + 1) . ',' . $value['_source']['SrcObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['PID'] . ',' . $value['_source']['TarObj']['MD5'] . ',,' . $value['_source']['SrcObj']['ParentName'] . ',' . $value['_source']['SrcObj']['CommandLine'] . ',,';
                } else if ($value['_source']['EventAction'] == 'CREATE_PROCESS' && $value['_source']['TarObj']['MD5'] == $v) {
                    $md5_contents .= substr($value['_source']['TarObj']['ImagePath'], strripos($value['_source']['TarObj']['ImagePath'], '\\') + 1) . ',' . $value['_source']['TarObj']['ProcessName'] . ',' . $value['_source']['TarObj']['PID'] . ',' . $value['_source']['TarObj']['MD5'] . ',,' . $value['_source']['TarObj']['ParentName'] . ',' . $value['_source']['TarObj']['CommandLine'] . ',,';
                } else if ($value['_source']['EventAction'] == 'CREATE_PROCESS' && $value['_source']['SrcObj']['MD5'] == $v) {
                    $md5_contents .= substr($value['_source']['SrcObj']['ImagePath'], strripos($value['_source']['SrcObj']['ImagePath'], '\\') + 1) . ',' . $value['_source']['SrcObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['PID'] . ',' . $value['_source']['SrcObj']['MD5'] . ',' . $value['_source']['TarObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['ParentName'] . ',' . $value['_source']['SrcObj']['CommandLine'] . ',,';
                }
                $md5_contents .= date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000) . "\n";
            }
            fwrite($myfile, iconv('UTF-8', 'GBK', $md5_contents));
        }
        //写ip的结果
        $ip_head = "计算机名,计算机IP,IP:端口,进程名,PID,文件路径,时间,\n";
        fwrite($myfile, iconv('UTF-8', 'GBK', $ip_head));
        foreach ($contents['IP'] as $k => $v) {
            $i_data = $this->filterForIP($v);
            foreach ($i_data['hits']['hits'] as $key => $value) {
                if ($value['_source']['EventAction'] == 'NETWORK_CONNECT') {
                    $ip_contents .= $value['_source']['ComputerName'] . ',' . $value['_source']['TarObj']['LocalIP'] . ',' . $value['_source']['TarObj']['RemoteIP'] . ':' . $value['_source']['TarObj']['RemotePort'] . ',' . $value['_source']['SrcObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['PID'] . ',' . $value['_source']['SrcObj']['ImagePath'] . ',' . date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000) . "\n";
                } else if ($value['_source']['EventAction'] == 'HTTP_REQUEST') {
                    $ip_contents .= $value['_source']['ComputerName'] . ',' . Sensor::getSensorIP([$value['_source']['SensorID']])[$value['_source']['SensorID']]['IP'] . ',' . $value['_source']['TarObj']['RemoteAdd'] . ':' . $value['_source']['TarObj']['RemotePort'] . ',' . $value['_source']['SrcObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['PID'] . ',' . $value['_source']['SrcObj']['ImagePath'] . ',' . date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000) . "\n";
                }
            }
            fwrite($myfile, iconv('UTF-8', 'GBK', $ip_contents));
        }
        //写url的结果
        $url_head = "计算机名,URL地址,进程名,PID,文件路径,时间,\n";
        fwrite($myfile, iconv('UTF-8', 'GBK', $url_head));
        foreach ($contents['URL'] as $key => $value) {
            $u_data = $this->filterForURL($value);
            foreach ($u_data['hits']['hits'] as $key => $value) {
                if ($value['_source']['EventAction'] == 'DNS_QUERY') {
                    $url_contents .= $value['_source']['ComputerName'] . ',' . $value['_source']['TarObj']['DomainName'] . ',' . $value['_source']['SrcObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['PID'] . ',' . $value['_source']['SrcObj']['ImagePath'] . ',' . date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000) . "\n";
                } else if ($value['_source']['EventAction'] == 'HTTP_REQUEST') {
                    $url_contents .= $value['_source']['ComputerName'] . ',' . $value['_source']['TarObj']['HttpURL'] . ',' . $value['_source']['SrcObj']['ProcessName'] . ',' . $value['_source']['SrcObj']['PID'] . ',' . $value['_source']['SrcObj']['ImagePath'] . ',' . date('Y-m-d H:i:s', $value['_source']['Timestamp'] / 1000) . "\n";
                }
            }
            fwrite($myfile, iconv('UTF-8', 'GBK', $url_contents));
        }
        fclose($myfile);
        //更改生成状态
        $ioc_model->create_percent = 100;
        $ioc_model->create_status = 1;
        $ioc_model->save();
        return ['status' => 'success'];
    }

    //拼接MD5查询语句
    private function filterForMD5($md5) {
        //查询语句
        $filter = [
            'from' => 0,
            'size' => 100,
            'query' => [
                'bool' => [
                    'should' => [
                        0 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PE_FILE']],
                                    1 => ['match' => ['TarObj.MD5' => $md5]]
                                ]
                            ]
                        ],
                        1 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PROCESS']],
                                    1 => ['match' => ['SrcObj.MD5' => $md5]]
                                ]
                            ]
                        ],
                        2 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'CREATE_PROCESS']],
                                    1 => ['match' => ['TarObj.MD5' => $md5]]
                                ]
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        return self::esRequest(json_encode($filter));
    }

    //拼接ip查询语句
    private function filterForIP($ip) {
        //查询语句
        $filter = [
            'from' => 0,
            'size' => 100,
            'query' => [
                'bool' => [
                    'should' => [
                        0 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'NETWORK_CONNECT']],
                                    1 => ['match' => ['TarObj.RemoteIP' => $ip]]
                                ]
                            ]
                        ],
                        1 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'HTTP_REQUEST']],
                                    1 => ['match' => ['TarObj.RemoteAdd' => $ip]]
                                ]
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        return self::esRequest(json_encode($filter));
    }

    //拼接url查询语句
    private function filterForURL($url) {
//        $url = addcslashes($url, '+-=&&||><!(){}[]^"~*?:\/');
//        $url = str_replace(array('+', '-', '=', '&&', '||', '>', '<', '!', '(', ')', '{', '}', '[', ']', '^', '"', '~', '*', '?', ':', '\\', '/'), array('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?'), $url);
        //查询语句
        $filter = [
            'from' => 0,
            'size' => 100,
            'query' => [
                'bool' => [
                    'should' => [
                        0 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'DNS_QUERY']],
//                                    1 => ['query_string' => ['default_field' => 'TarObj.DomainName.keyword', 'query' => $url]]
                                    1 => ['term' => ['TarObj.DomainName.keyword' => $url]]
//                                    1 => ['match' => ['TarObj.DomainName' => $url]]
//                                    1 => ['regexp' => ['TarObj.DomainName.keyword' => $url . '$']]
                                ]
                            ]
                        ],
                        1 => [
                            'bool' => [
                                'must' => [
                                    0 => ['match' => ['EventAction' => 'HTTP_REQUEST']],
//                                    1 => ['query_string' => ['default_field' => 'TarObj.HttpURL.keyword', 'query' => $url]]
                                    1 => ['term' => ['TarObj.HttpURL.keyword' => $url]]
//                                    1 => ['match' => ['TarObj.HttpURL' => $url]]
//                                    1 => ['regexp' => ['TarObj.HttpURL.keyword' => $url . '$']]
                                ]
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => ['Timestamp' => ['order' => 'desc']]
        ];
        return self::esRequest(json_encode($filter));
    }

    //获取IOC扫描结果列表
    public function actionGetIocList($page = 1, $rows = 15) {
        $this->isAPI();
        if (!Yii::$app->request->isGet) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'bad request';
        }
        $post = json_decode(Yii::$app->request->getRawBody(), true);
        $page = empty($post['page']) ? $page : $post['page'];
        $rows = empty($post['rows']) ? $rows : $post['rows'];
        $page = (int) $page;
        $rows = (int) $rows;
        $query = IocScanning::find()->orderBy('id DESC');
        $count = (int) $query->count();
        $maxPage = ceil($count / $rows);
        $page = $page > $maxPage ? $maxPage : $page;
        $iocList = $query->offSet(($page - 1) * $rows)->limit($rows)->asArray()->all();
        return ['status' => 'success', 'list' => $iocList, 'current_page' => $page, 'total_count' => $count, 'max_page' => $maxPage];
    }

    //下载csv文件的方法
    public function actionTestDownloadCsv() {
        $this->isAPI();
        $get = Yii::$app->request->get();
        $ioc_data = IocScanning::find()->where(['and', ['=', 'id', $get['id']], ['=', 'download_file_name', $get['download_file_name']]])->asArray()->one();
        if (empty($ioc_data) || $ioc_data['create_status'] != 1) {
            return ['status' => 'fail', 'errorMessage' => 'csv文件选择失败'];
        }
        if (!file_exists(Yii::getAlias('@frontend') . '/web/csvfile/' . $get['download_file_name'])) {
            return ['status' => 'fail', 'errorMessage' => '该文件不存在'];
        }
        return ['status' => 'success'];
    }

    //下载csv文件的方法
    public function actionDownloadCsv() {
        $this->isAPI();
        $get = Yii::$app->request->get();
        \YII::$app->response->sendFile(Yii::getAlias('@frontend') . '/web/csvfile/' . $get['download_file_name']);
    }

    //删除csv的方法
    public function actionDelCsv() {
        $this->isAPI();
        $data['status'] = 'fail';
        //参数验证
        if (!Yii::$app->request->isDelete) {
            $data['errorMessage'] = 'bad request';
        }
        $parames = json_decode(Yii::$app->request->getRawBody(), true);
        if (!array_key_exists('id', $parames) || !array_key_exists('download_file_name', $parames)) {
            $data['errorMessage'] = 'bad parames';
        }
        //删除数据库记录和文件
        $file_url = Yii::getAlias('@frontend') . '/web/csvfile/';
        IocScanning::deleteAll(['=', 'id', $parames['id']]);
        if (file_exists($file_url . $parames['download_file_name'])) {
            unlink($file_url . $parames['download_file_name']);
        }
        return ['status' => 'success'];
    }

    public function actionSendCommand() {
        $this->isAPI();
        if (!Yii::$app->request->isPost) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Not post request';
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $RawBody = trim(Yii::$app->request->getRawBody());
            $post = json_decode($RawBody, true);
        }
        if (empty($post)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Rawbody not JSON';
            return $data;
        }
        $command = new Command();
        $command->Type = Command::MSG_M2E_SEARCH;
        $command->CommandID = Command::createUuid();
        $post['CommandID'] = $command->CommandID;
        $command->data = $post;
        $command->send();
        $command->save();
        if ($command->status == Command::STATUS_UNSENT) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Command send failed';
            return $data;
        }
        $data = ['status' => 'success', 'CommandID' => $command->CommandID];
        return $data;
    }

    public function actionGetResult() {
        $this->isAPI();
        if (!Yii::$app->request->isPost) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Not post request';
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $RawBody = trim(Yii::$app->request->getRawBody());
            $post = json_decode($RawBody, true);
        }
        if (empty($post)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Rawbody not JSON';
            return $data;
        }
        $command = Command::find()->where(['CommandID' => $post['CommandID']])->one();
        if (empty($command)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Without this command.';
            Logger::warning('Without this command.');
            Logger::warning($post);
        }
        $commandData = $command->data;
        if (array_key_exists('Result', $commandData)) {
            $data = ['status' => 'success', 'Result' => $commandData['Result']];
        } else {
            $data = ['status' => 'fail', 'errorMessage' => 'Please wait.'];
        }
        return $data;
    }

    public function actionGetSensor() {
        $this->isAPI();
        if (!Yii::$app->request->isPost) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Not post request';
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $RawBody = trim(Yii::$app->request->getRawBody());
            $post = json_decode($RawBody, true);
        }
        if (empty($post)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Rawbody not JSON';
            return $data;
        }

        if ($post['ComputerName'] != '') {
            $whereList['ComputerName'] = $post['ComputerName'];
        }
        if ($post['IP'] != '') {
            $whereList['IP'] = $post['IP'];
        }
        if (isset($whereList)) {
            $sensorList = Sensor::find()->where($whereList)->all();
            $sensorList = ArrayHelper::toArray($sensorList);
        } else {
            $sensorList = [];
        }
        $data = ['status' => 'success', 'data' => $sensorList];
        return $data;
    }

    //封装es请求
    public function esRequest($data) {
        $headerArray = array("Content-type:application/json;charset='utf-8'", "Accept:application/json");
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1:9200/20*/icatch/_search');
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArray);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return json_decode($output, true);
    }

}
